using System.Windows.Forms;

namespace OhioState.Controls
{
	/// <summary>
	/// ExaminerMouseHandler provides a set of mouse event handlers that simulate a
    /// virtual trackball with the left-mouse, a translation hand with the middle-
    /// mouse and a perspective zoom (or zoom lens) with the right-mouse button.
	/// </summary>
	/// 
    public class ExaminerMouseHandler : TransformMouseController
	{
        /// <summary>
        /// Constuctor.
        /// </summary>
        /// <param name="targetControl">The control to which we should subscribe our
        /// mouse events.</param>
        /// <param name="setKeyboardFocusOnMouseDown">A Boolean indicating whether
        /// the control should recieve the keyboard focus (true) when the mouse is
        /// clicked (mouse-down) within the control. This is needed if the user wishes
        /// to control the cameras with keyboard keys.</param>
        public ExaminerMouseHandler()
            : base()
		{
			//
			// The cameraCtrl controls need to be attached to the mouse handler's, but we will delay
			//    that until after a mouse down. The Examiner functions below determine what to 
			//    attach on a mouse down event.
			//
		}
        protected override void SetOwnerControl( Control control )
        {
            if (OwnerControl != null)
            {
                OwnerControl.MouseDown -= new MouseEventHandler(LeftRotate);
                OwnerControl.MouseDown -= new MouseEventHandler(MiddlePan);
                OwnerControl.MouseDown -= new MouseEventHandler(RightZoom);
            }
            base.SetOwnerControl(control);
            if (OwnerControl != null)
            {
                OwnerControl.MouseDown += new MouseEventHandler(LeftRotate);
                OwnerControl.MouseDown += new MouseEventHandler(MiddlePan);
                OwnerControl.MouseDown += new MouseEventHandler(RightZoom);
            }
        }

		#region Mouse Callbacks
		protected void LeftRotate(object sender, System.Windows.Forms.MouseEventArgs e) 
		{
			//
			// Check to see which mouse button was pressed.
			// A bit-wise and-mask is used for this.
			//
			if( (e.Button & MouseButtons.Left) == MouseButtons.Left )
			{
				if( this.NowInteracting == false )
				{
                    System.Windows.Forms.Control currentCtrl = (System.Windows.Forms.Control)sender;
					//
					// Capture the Mouse movements, even those outside of this window.
					// This statement ensures that all mouse movement is associated with this
					//   process until the mouse button is released.
					//
					currentCtrl.Capture = true;
					// Change the cursor
					currentCtrl.Cursor = Cursors.WaitCursor;
					//
					// Add the Mouse Moves event handlers and the mouse up event handler.
					//
					m_MouseMoveDelegate = new MouseEventHandler( transformCtrl.Trackball );
					currentCtrl.MouseMove += m_MouseMoveDelegate;
					m_MouseUpDelegate = new MouseEventHandler( My_MouseUp );
					currentCtrl.MouseUp += m_MouseUpDelegate;
					//
					// Record this mouse position. 
					//
					transformCtrl.SetMousePosition( e.X, e.Y );

					BeginManipulation();
				}
			}
		}
		protected void RightZoom(object sender, System.Windows.Forms.MouseEventArgs e) 
		{
			//
			// Check to see which mouse button was pressed.
			// A bit-wise and-mask is used for this.
			//
			if( (e.Button & MouseButtons.Right) == MouseButtons.Right )
			{
				if( this.NowInteracting == false )
				{
                    System.Windows.Forms.Control currentCtrl = (System.Windows.Forms.Control)sender;
					//
					// Add a Mouse Move event handler to zoom the cameraCtrl. Also set
					//   the mouse up event handler.
					//
					//
					// Capture the Mouse movements, even those outside of this window.
					// This statement ensures that all mouse movement is associated with this
					//   process until the mouse button is released.
					//
					currentCtrl.Capture = true;
					// Change the cursor
					currentCtrl.Cursor = Cursors.SizeWE;
					//
					m_MouseMoveDelegate = new MouseEventHandler( transformCtrl.ZoomLens );
					currentCtrl.MouseMove += m_MouseMoveDelegate;
					m_MouseUpDelegate = new MouseEventHandler( My_MouseUp );
					currentCtrl.MouseUp += m_MouseUpDelegate;
					//
					// Record this mouse position. 
					//
					transformCtrl.SetMousePosition( e.X, e.Y );

					BeginManipulation();
				}
			}
		}
		protected void MiddlePan(object sender, System.Windows.Forms.MouseEventArgs e) 
		{
			//
			// Check to see which mouse button was pressed.
			// A bit-wise and-mask is used for this.
			//
			if( (e.Button & MouseButtons.Middle) == MouseButtons.Middle )
			{
				if( this.NowInteracting == false )
				{
                    System.Windows.Forms.Control currentCtrl = (System.Windows.Forms.Control)sender;
					//
					// Add a Mouse Move event handler to translate the cameraCtrl. Also set 
					//   the mouse up event handler.
					//
					// Capture the Mouse movements, even those outside of this window.
					// This statement ensures that all mouse movement is associated with this
					//   process until the mouse button is released.
					//
					currentCtrl.Capture = true;
					//
					// Change the cursor.
					currentCtrl.Cursor = Cursors.Hand;
					m_MouseMoveDelegate = new MouseEventHandler( transformCtrl.Translate );
					currentCtrl.MouseMove += m_MouseMoveDelegate;
					m_MouseUpDelegate = new MouseEventHandler( My_MouseUp );
					currentCtrl.MouseUp += m_MouseUpDelegate;
					//
					// Record this mouse position. 
					//
					transformCtrl.SetMousePosition( e.X, e.Y );

					BeginManipulation();
				}
			}
		}
		#endregion Mouse Callbacks
	}
}
